"""
Case Type   : 归档日志目录
Case Name   : 归档日志目录删除
Create At   : 2020/8/12
Owner       : @zou_jialiang0505326387
Description :
    1、设置归档相关参数
    2、test1：删除归档目录，之后提交事务进行归档操作
    3、test2：执行提交事务脚本正在归档，删除归档目录
Expect      :
    1、设置归档相关参数成功
    2、重启数据库成功
    3、test1：删除归档目录，之后提交事务进行归档操作，pg日志打印相应报错，数据库状态正常
    4、test2：执行提交事务脚本正在归档，删除归档目录，数据库状态正常
History     :
    2021/05/17 modified by @peilinqian 优化脚本逻辑，增加必要打印信息;增加test2故障结果逻辑处理
"""

import os
import time
import unittest

from testcase.utils.ComThread import ComThread
from testcase.utils.Common import Common
from testcase.utils.CommonSH import *
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class NoneArchivePath(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.log = Logger()
        cls.log.info('----Opengauss_Reliability_Dbsys_Case035.py start----')
        cls.dbUserNode = Node(node='dbuser')
        cls.conf_path = os.path.join(macro.DB_INSTANCE_PATH,
                                     macro.DB_PG_CONFIG_NAME)
        cls.log.info(cls.conf_path)
        cls.arch_path = macro.ARCH_PATH
        cls.node_name = macro.DN_NODE_NAME.split('/')[0]
        cls.log_path = os.path.join(macro.PG_LOG_PATH, cls.node_name)
        cls.log.info(cls.log_path)
        cls.sh = CommonSH()
        cls.com = Common()
        cls.Constant = Constant()

    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log.info('----1、修改归档参数----')
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   'archive_mode = on')
        self.assertTrue(msg)
        arch_command = f'cp --remove-destination %p {self.arch_path}/%f'
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   f"archive_command ='{arch_command}'")
        self.assertTrue(msg)
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   'archive_timeout = 30')
        self.assertTrue(msg)
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   'checkpoint_segments = 10')
        self.assertTrue(msg)

        self.log.info('----修改配置文件成功----')
        sql_result = self.sh.executDbSql('show archive_mode;'
                                         'show archive_command;'
                                         'show archive_timeout;'
                                         'show checkpoint_segments;')
        self.log.info(sql_result)

    def test_del_archivepath1(self):
        self.log.info('----test1：删除归档目录，之后提交事务进行归档操作----')
        self.log.info('----查询归档路径----')
        exits_cmd = f'ls {self.arch_path}'
        self.log.info(exits_cmd)
        exits_msg = self.dbUserNode.sh(exits_cmd).result()
        self.log.info(exits_msg)
        if self.Constant.NO_FILE_MSG not in exits_msg:
            self.log.info('----删除归档路径----')
            rm_cmd = f'rm -vrf {self.arch_path}'
            self.log.info(rm_cmd)
            self.dbUserNode.sh(rm_cmd).result()
            exits_cmd = f'ls {self.arch_path}'
            exits_msg = self.dbUserNode.sh(exits_cmd).result()
            self.log.info(exits_msg)
            self.assertIn(self.Constant.NO_FILE_MSG, exits_msg)

        self.log.info('----开始执行插入事务----')
        msg = self.com.createLargeNumTable(self.dbUserNode,
                                           't_test',
                                           1,
                                           1000000)
        self.log.info(msg)

        self.log.info('----查询主备状态----')
        status = self.sh.getDbClusterStatus('status')
        self.assertTrue(status)

        self.log.info('----查看日志关键信息----')
        time.sleep(120)
        find_file_cmd = f'ls -t {self.log_path} |grep postgresql |head -n1'
        self.log.info(find_file_cmd)
        msg = self.dbUserNode.sh(find_file_cmd).result()
        self.log.info(msg)
        cat_file_cmd = f'cat {os.path.join(self.log_path, msg)}'
        self.log.info(cat_file_cmd)
        msg = self.dbUserNode.sh(cat_file_cmd).result()
        self.log.info(msg)
        self.assertIn(self.Constant.FAILED_ARCHIVE_MSG, msg)

    def test_del_archivepath2(self):
        self.log.info('----test2：执行提交事务脚本正在归档，删除归档目录----')
        self.log.info('----查询归档路径----')
        exits_cmd = f'ls {self.arch_path}'
        self.log.info(exits_cmd)
        exits_msg = self.dbUserNode.sh(exits_cmd).result()
        self.log.info(exits_msg)
        if self.Constant.NO_FILE_MSG in exits_msg:
            self.log.info('----不存在目录进行目录创建----')
            mk_cmd = f'mkdir {self.arch_path}'
            msg = self.dbUserNode.sh(mk_cmd).result()
            self.assertEqual(msg, '')
            self.log.info('----查询归档路径----')
            exits_cmd = f'ls {self.arch_path}'
            self.log.info(exits_cmd)
            exits_msg = self.dbUserNode.sh(exits_cmd).result()
            self.log.info(exits_msg)

        self.log.info('----启动新线程插入数据----')
        insert_thread = ComThread(self.com.createLargeNumTable,
                                  args=(self.dbUserNode,
                                        't_test',
                                        1,
                                        10000000,))
        insert_thread.setDaemon(True)
        insert_thread.start()

        time.sleep(5)

        self.log.info('----提交事务正在归档的时候删除归档目录----')
        self.log.info('----查询归档路径----')
        exits_cmd = f'ls {self.arch_path}'
        self.log.info(exits_cmd)
        exits_msg = self.dbUserNode.sh(exits_cmd).result()
        self.log.info(exits_msg)
        self.log.info('----删除归档路径----')
        rm_cmd = f'rm -vrf {self.arch_path}'
        self.log.info(rm_cmd)
        rm_result = self.dbUserNode.sh(rm_cmd).result()
        self.log.info(rm_result)
        exits_cmd = f'ls {self.arch_path}'
        exits_msg = self.dbUserNode.sh(exits_cmd).result()
        self.log.info(exits_msg)
        if 'cannot remove' in rm_result:
            self.log.info('归档过程删除归档路径失败！！！')
        else:
            self.assertIn(self.Constant.NO_FILE_MSG, exits_msg)

        self.log.info('----插入数据正常完成----')
        insert_thread.join()
        insert_result = insert_thread.get_result()
        self.log.info(insert_result)
        self.assertIn('INSERT 0 10000000', insert_result)

        self.log.info('----查询主备状态----')
        status = self.sh.getDbClusterStatus('status')
        self.assertTrue(status)

    def tearDown(self):
        self.log.info('----恢复归档参数----')
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   'archive_mode = off')
        self.assertTrue(msg)
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   'archive_timeout = 0')
        self.assertTrue(msg)
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   'checkpoint_segments = 64')
        self.assertTrue(msg)

        self.log.info('----修改配置文件成功----')
        sql_result = self.sh.executDbSql('show archive_mode;'
                                         'show archive_command;'
                                         'show archive_timeout;'
                                         'show checkpoint_segments;')
        self.log.info(sql_result)

        self.log.info('----清理数据----')
        msg = self.com.createLargeNumTable(self.dbUserNode,
                                           't_test',
                                           del_sign=True)
        self.log.info(msg)

        self.log.info('----删除创建的文件----')
        exits_cmd = f'ls {self.arch_path}'
        msg = self.dbUserNode.sh(exits_cmd).result()
        if self.Constant.NO_FILE_MSG not in msg:
            rm_cmd = f'rm -vrf {self.arch_path}'
            self.log.info(rm_cmd)
            self.dbUserNode.sh(rm_cmd).result()
            exits_cmd = f'ls {self.arch_path}'
            exits_result = self.dbUserNode.sh(exits_cmd).result()
            self.log.info(exits_result)

        self.log.info('----reliability_dbsys035 执行完成----')
